﻿using System;
using System.Linq;
using System.Windows.Forms;
using System.Configuration;
using System.Drawing;
using System.Reflection;
using Infragistics.Win.Misc;
using Infragistics.Win.UltraWinTabControl;
using Titan.WinFormSys.Entity;
using System.Xml;
using System.IO;
using System.Collections.Generic;

namespace Titan.WinFormSys
{
    /// <summary>
    /// 主窗体
    /// </summary>
    public sealed partial class FrmMain : RibbonForm
    {

        /// <summary>
        /// 重新登录标识
        /// </summary>
        public static bool LoginAgain;

        private Dictionary<string, IList<string>> dtMenuName { get; set; }//string主菜单  IList<string>该主菜单下的子菜单 置于内存中

        /// <summary>
        /// 程序主窗体
        /// </summary>
        public FrmMain()
        {
            InitializeComponent();
            Text = ConfigurationManager.AppSettings["Title"];
            rb_ModifyPwd.Click += ModifyPwd_Click;
            rb_About.Click += AboutSoft;
            rb_LoginA.Click += UserLoginAgain;
            rb_Exit.Click += UserExit;
            panLine.Height = 1;

            this.rb_main.OrbDropDown.MenuItems.Remove(this.rb_About);
            this.dtMenuName = new Dictionary<string, IList<string>>();

            FormOperate.F_MainForm = this;
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            FormInit();
        }

        /// <summary>
        /// 窗体初始化
        /// </summary>
        private void FormInit()
        {
            CreateRibbonTab();
            ViewUserInfo();
        }

        private void ViewUserInfo()
        {
            ultraStatusBar1.Panels[0].Text = @"登陆用户：" + FrmBase.UserInfo.ChineseName;
            ultraStatusBar1.Panels[1].Text = @"登陆时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ModifyPwd_Click(object sender, EventArgs e)
        {
            new FrmModifyPwd().ShowDialog();
        }

        /// <summary>
        /// 重新登录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void UserLoginAgain(object sender, EventArgs e)
        {
            LoginAgain = true;
            //if (new FrmLogin().ShowDialog() == DialogResult.OK)
            //    FormInit();
            if (new FrmIndex().ShowDialog() == DialogResult.OK)
                FormInit();
        }

        /// <summary>
        /// 退出系统
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void UserExit(object sender, EventArgs e)
        {
            new FrmLogout().ShowDialog();
        }

        /// <summary>
        /// 关于本软件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AboutSoft(object sender, EventArgs e)
        {
            new FrmAbout().ShowDialog();
        }

        private void CreateRibbonTab()
        {
            rb_main.Tabs.Clear();
            //var pList = from p in FrmBase.UserInfo.Powers where string.IsNullOrEmpty(p.ParentId) orderby p.SortIndex select p;
            var pList = from p in FrmBase.UserInfo.Powers select p;

            /////add 限制用户菜单
            var filePath = Environment.CurrentDirectory + @"\ClientMenuList.xml";
            if (File.Exists(filePath))
            {
                var xmlDoc = new XmlDocument();
                xmlDoc.Load(filePath);
                var xn = xmlDoc.SelectSingleNode("Files");
                if (xn == null) return;
                var xnl = xn.ChildNodes;
                foreach (var strAssemblyName in from XmlNode cxn in xnl
                                                let xmlAttributeCollection = cxn.Attributes
                                                where xmlAttributeCollection != null
                                                where xmlAttributeCollection != null
                                                select xmlAttributeCollection["fileName"].Value.ToUpper() + "^_^" + xmlAttributeCollection["ver"].Value.ToUpper())
                {
                    int index = strAssemblyName.IndexOf("^_^");
                    string strSubMenu = strAssemblyName.Substring(0, index);
                    string strMenu = strAssemblyName.Substring(index + 3, strAssemblyName.Length - index - 3);
                    if (!this.dtMenuName.ContainsKey(strMenu))//判断是否已经包含
                    {
                        IList<string> TmpSubMenu = new List<string>();
                        TmpSubMenu.Add(strSubMenu);
                        dtMenuName.Add(strMenu, TmpSubMenu);
                    }
                    else
                    {
                        this.dtMenuName[strMenu].Add(strSubMenu);
                    }
                }
            }
            else
                return;

            foreach (var powerEntity in pList)
            {
                if (dtMenuName.ContainsKey(powerEntity.Name))
                {
                    var mainRt = GetRibbonTab(powerEntity.Name);
                    AddSubMenu(mainRt, powerEntity);
                    rb_main.Tabs.Add(mainRt);
                }
            }
            //rb_main.CloseButton.Visible = true;
            rb_main.Minimized = false;
        }

        private static RibbonTab GetRibbonTab(string name)
        {
            var rt = new RibbonTab(name);
            return rt;
        }
		private static RibbonTab AddRibbonPanel(RibbonTab rt, string name)
		{
			var rp = new RibbonPanel(name);
			rp.ButtonMoreVisible = false;
			rp.ButtonMoreEnabled = false;
			rt.Panels.Add(rp);
			return rt;
		}

		private void AddSubMenu(RibbonTab rt, RolePowersEntity pe)
        {
            var pList = from p in FrmBase.UserInfo.Powers where p.ParentId == pe.Id orderby p.SortIndex select p;
            var strFilePath = Environment.CurrentDirectory + "\\Image\\";
            if (!pList.Any()) return;
            foreach (var rb in pList.Select(page => new RibbonButton(page.Name)
            {
                Image = Image.FromFile(File.Exists(strFilePath + page.ImageUrl) ? strFilePath + page.ImageUrl : strFilePath + "Default.png"),
                Tag = page.NavigateUrl
            }))
            {
                if (rt.Panels.Count == 0)
                {
                    rb.Click += subMenu_Click;
                    rt = AddRibbonPanel(rt, rb.Text);
					rt.Panels[0].Items.Add(rb);
                }
                else
                {
                    var count = rt.Panels.Count;
                    var isFind = false;
                    for (var i = 0; i < count; i++)
                    {
                        if (rt.Panels[i].Text == rb.Text)
                        {
							isFind = true;
                        }
                    }
                    if (!isFind)
                    {
                        rb.Click += subMenu_Click;
						rt = AddRibbonPanel(rt, rb.Text);
						rt.Panels[rt.Panels.Count-1].Items.Add(rb);
                    }
                }
            }
        }

        /// <summary>
        /// 菜单单击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void subMenu_Click(object sender, EventArgs e)
        {
            rb_main.Minimized = false;
            var rb = (RibbonButton)sender;
            var formName = rb.Tag.ToString();
            var strTitle = rb.Text;

            if (formName.Length < 1)
            {
                MessageBox.Show(@"窗体名称参数长度有误");
                return;
            }
            AddModule(GetControl(formName), formName, strTitle);
        }


        private void tc_MainFrm_TabClosed(object sender, TabClosedEventArgs e)
        {
            tc_MainFrm.Tabs.Remove(e.Tab);
        }

        private void tc_MainFrm_TabClosing(object sender, TabClosingEventArgs e)
        {
            foreach (Control ctr in e.Tab.TabPage.Controls)
            {
                if (ctr is FrmBase)
                    ((FrmBase)ctr).Close();
            }
        }


        public void DoExit()
        {
            //1.this.Close();   只是关闭当前窗口，若不是主窗体的话，是无法退出程序的，另外若有托管线程（非主线程），也无法干净地退出； 
            //2.Application.Exit();  强制所有消息中止，退出所有的窗体，但是若有托管线程（非主线程），也无法干净地退出； 
            //3.Application.ExitThread(); 强制中止调用线程上的所有消息，同样面临其它线程无法正确退出的问题； 
            //4.System.Environment.Exit(0);   这是最彻底的退出方式，不管什么线程都被强制退出，把程序结束的很干净。 
            this.Close();
            System.Threading.Thread.Sleep(500);
            System.Environment.Exit(0);
        }

        /// <summary>
        /// 添加模块
        /// </summary>
        /// <param name="newCtl"></param>
        /// <param name="tagStr"></param>
        /// <param name="title"></param>
        private void AddModule(Form newCtl, string tagStr, string title)
        {
            var isExist = false;
            if (newCtl == null)
            {
                MessageBox.Show(@"未找到该窗体，请检查配置文件");
                return;
            }
            foreach (var tab in tc_MainFrm.Tabs)
            {
                if (tab.Tag != null && tab.Tag.ToString() == tagStr)
                {
                    tab.Selected = true;
                    isExist = true;
                    break;
                }
            }
            if (isExist) return;
            var newTpt = new UltraTabPageControl
            {
                Text = title,
                Tag = tagStr
            };
            newCtl.Text = title;
            newCtl.Dock = DockStyle.Fill;
            newCtl.FormBorderStyle = FormBorderStyle.None;
            newCtl.Show();
            newTpt.Controls.Add(newCtl);
            tc_MainFrm.Controls.Add(newTpt);
            tc_MainFrm.Tabs[tc_MainFrm.Tabs.Count - 1].Text = title;
            tc_MainFrm.Tabs[tc_MainFrm.Tabs.Count - 1].Tag = tagStr;

        }

        /// <summary>
        /// 获取窗体对象
        /// </summary>
        /// <param name="formName"></param>
        /// <returns></returns>
        private static Form GetControl(string formName)
        {
            return FindFormFromHashtable(formName);
        }

        /// <summary>
        /// 从hashtable中找到已反射的窗体对象
        /// </summary>
        /// <param name="formName"></param>
        /// <returns></returns>
        private static FrmBase FindFormFromHashtable(string formName)
        {
            try
            {
                var localObject = FindObject(formName);
                var vtype = localObject.GetType(formName);
                var vobject = Activator.CreateInstance(vtype);
                return vobject as FrmBase;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 从已反射的DLL中找到该DLL对象
        /// </summary>
        /// <param name="formName"></param>
        /// <returns></returns>
        private static Assembly FindObject(string formName)
        {
            var strKey = formName.Substring(0, formName.LastIndexOf(".", StringComparison.Ordinal)).ToUpper();
            if (AssemblyEntity.AssemblyHt.ContainsKey(strKey))
                return (Assembly)AssemblyEntity.AssemblyHt[strKey];

            var ass = Assembly.Load(formName);//加载DLL文件
            AssemblyEntity.AssemblyHt.Add(strKey, ass);//将加载的DLL对象存在hashtable中                   
            return AssemblyEntity.AssemblyHt[strKey] as Assembly;//返回对象
        }

        private void FrmNewMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if (MessageBox.Show(@"确定并退出程序吗？", @"提示信息", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
            //    e.Cancel = true;
        }

        private void FrmNewMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.ExitThread();
            Application.Exit();
        }

        private void tc_MainFrm_Click(object sender, EventArgs e)
        {
            rb_main.Minimized = true;
        }

        private void rb_main_ActiveTabChanged(object sender, EventArgs e)
        {
            rb_main.Minimized = false;
        }

    }
}
